﻿using Ekton_Manage_DomainCore.Aggregate;
using Ekton_Manage_DTO.RequestModels.Auth;
using Ekton_Manage_DTO.RequestModels.User;
using Ekton_Manage_DTO.RequestModels.UserControl;
using Ekton_Manage_Framework.Methods;
using Ekton_Manage_Framework.Redis;
using Ekton_Manage_IBusiness;
using Ekton_Manage_InfrastructureCore.Common;
using Ekton_Manage_InfrastructureCore.Repositories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using static Ekton_Manage_DTO.CommonModels.DtoFileModel;

namespace Ekton_Manage_Web.Controllers
{
    /// <summary>
    /// 用户信息
    /// </summary>
    /// 
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize("Permission")]
    public class HomeController : ControllerBase
    {

        private readonly ISelectSysUser _selectUserList;
        private readonly IUserBusiness _userBusiness;
        private readonly CommonHelper _commonHelper;
        private readonly IConfiguration _configuration;
        private readonly IBaseRepository<sys_user, int> _basesysuserRepository;
        private readonly IBaseRepository<user_list, int> _userListrepository;
        private readonly HelpRedisFuncList _helpRedisFuncList;
        private readonly IBaseRepository<sys_role, int> _basesysroleRepository;
        public HomeController( ISelectSysUser selectUserList, IConfiguration configuration,
                              IUserBusiness userBusiness,
                              CommonHelper commonHelper,
                              IBaseRepository<sys_user, int> basesysuserRepository,
                              IBaseRepository<user_list, int> userListrepository,
                              HelpRedisFuncList helpRedisFuncList,
                             IBaseRepository<sys_role, int> basesysroleRepository)
        {

            _selectUserList = selectUserList;
            _configuration = configuration;
            _userBusiness = userBusiness;
            _commonHelper = commonHelper;
            _basesysuserRepository = basesysuserRepository;
            _userListrepository = userListrepository;
            _helpRedisFuncList = helpRedisFuncList;
            _basesysroleRepository = basesysroleRepository;
        }
        /// <summary>
        /// 后台用户登录
        /// </summary>
        /// <param name="parame"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> GetToken([FromBody] CheckIdentity parame)
        {
            #region 登录验证
            dynamic userData = await _userBusiness.CheckLogin(parame.loginName, parame.password);
            var userInfo = await _basesysuserRepository.QuerySingleData(m => m.account == parame.loginName);
            if (userData is null) return Ok(new { msg = "用户名或密码错误!", token = default(string), code = 400, });
            if (userInfo is null)
            {
                return Ok(new { msg = "没有该用户!", token = default(string), code = 400, });

            }
            else
            {
                if (userInfo.state == 2)
                {
                    return Ok(new { msg = "该用户已被停用!", code = 202, });
                }
            }
            #endregion
            #region JWT-Token
            Const.ValidAudience = parame.loginName + parame.password + DateTime.Now.ToString();
            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
                new Claim(ClaimTypes.NameIdentifier, JsonConvert.SerializeObject(new{ id=userData.id,name=parame.loginName,platform="backstage"})),
            };
            //sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
            var token = new JwtSecurityToken(
               issuer: Const.Domain, //颁发者
               audience: "Ekton-Client",
               expires: DateTime.Now.AddHours(48),// 过期时间
               signingCredentials: creds, //签名证书
               claims: claims);//自定义参数
            #endregion
            //获取btnCode
            var RoleInfo = await _basesysroleRepository.QuerySingleData(m=>m.id == userInfo.role);
            return Ok(new
            {
                msg = "登陆成功!",
                token = new JwtSecurityTokenHandler().WriteToken(token),
                code = 200,
                success = true,
                uid = userData.id,
                userName = parame.loginName,
                role = userInfo.role,
                role_name = userInfo.role_name,
                token_type = "Bearer",
                btnCodes = RoleInfo.btnCodes,
                expires_in = await _commonHelper.ConvertDateTimeToInt(DateTime.Now.AddMinutes(30))
            });
        }

        /// <summary>
        /// 后台用户忘记密码
        /// </summary>
        /// <remarks>
        /// 1.不需要token，修改密码部分也不需要
        /// 2.邮箱验证
        /// </remarks>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<Message> PostUserPwd([FromBody] DtoUserPwd request)
        {
            return await _userBusiness.PostUserPwd(request);
        }

        /// <summary>
        /// 查询全部用户
        /// </summary>
        /// <param name="query"></param>
        [HttpGet]
        public async Task<MessageModel<PageModel<user_list>>> GetUserList([FromQuery] QueryDataParame query)
        {
            var result = await _userBusiness.GetUserList(query);

            return new MessageModel<PageModel<user_list>>
            {
                msg = "数据获取成功",
                response = new PageModel<user_list>
                {
                    pageIndex = query.pageIndex,
                    pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(result.Item2) / query.pageSize)),
                    dataCount = result.Item2,
                    pageSize = query.pageSize,
                    data = result.Item1
                }
            };
        }

        /// <summary>
        /// 导出用户列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<FileResult> ExportData([FromBody] ExportFormData formData)
        {
            List<user_list> data = new();
            if (formData.list.Count < 1)
                data = await _userListrepository.QueryTableList(m => true);
            else
                data = await _userListrepository.QueryTableList(m => formData.list.Contains(m.id));

            //创建一个新的excel文件
            HSSFWorkbook book = new HSSFWorkbook();
            //创建一个工作区
            ISheet sheet = book.CreateSheet("sheet1");
            //创建一行
            IRow row = sheet.CreateRow(0);
            for (int i = 0; i < 10; i++)
            {
                sheet.SetColumnWidth(i, 23 * 156);
            }
            sheet.SetColumnWidth(4, 30 * 156);
            sheet.SetColumnWidth(1, 21 * 156);
            //定义一个样式
            ICellStyle setborder = book.CreateCellStyle();
            setborder.BorderLeft = BorderStyle.Thin;
            setborder.BorderRight = BorderStyle.Thin;
            setborder.BorderBottom = BorderStyle.Thin;
            setborder.BorderTop = BorderStyle.Thin;

            //文字水平和垂直对齐方式
            setborder.VerticalAlignment = VerticalAlignment.Center;//垂直居中
            setborder.Alignment = HorizontalAlignment.Center;//水平居中
            setborder.WrapText = true;//自动换行

            //再定义一个样式，用来设置最上面标题行的样式
            ICellStyle setborderdeth = book.CreateCellStyle();
            setborderdeth.BorderLeft = BorderStyle.Thin;
            setborderdeth.BorderRight = BorderStyle.Thin;
            setborderdeth.BorderBottom = BorderStyle.Thin;
            setborderdeth.BorderTop = BorderStyle.Thin;

            //定义一个字体样式
            IFont font = book.CreateFont();
            //将字体设为红色
            font.Color = IndexedColors.Red.Index;
            setborderdeth.SetFont(font);
            setborderdeth.VerticalAlignment = VerticalAlignment.Center;
            setborderdeth.Alignment = HorizontalAlignment.Center;
            setborderdeth.WrapText = true;

            row.HeightInPoints = 25;
            //设置单元格的值
            row.CreateCell(0).SetCellValue("序号");
            row.GetCell(0).CellStyle = setborderdeth;
            row.CreateCell(1).SetCellValue("登录账号");
            row.GetCell(1).CellStyle = setborderdeth;
            row.CreateCell(2).SetCellValue("用户姓名");
            row.GetCell(2).CellStyle = setborderdeth;
            row.CreateCell(3).SetCellValue("性别");
            row.GetCell(3).CellStyle = setborderdeth;
            row.CreateCell(4).SetCellValue("所属公司组织");
            row.GetCell(4).CellStyle = setborderdeth;
            row.CreateCell(5).SetCellValue("联系手机");
            row.GetCell(5).CellStyle = setborderdeth;
            row.CreateCell(6).SetCellValue("邮箱Email");
            row.GetCell(6).CellStyle = setborderdeth;
            row.CreateCell(7).SetCellValue("状态");
            row.GetCell(7).CellStyle = setborderdeth;
            row.CreateCell(8).SetCellValue("创建人");
            row.GetCell(8).CellStyle = setborderdeth;
            row.CreateCell(9).SetCellValue("创建时间");
            row.GetCell(9).CellStyle = setborderdeth;
            for (int i = 0; i < data.Count; i++)
            {
                IRow row1 = sheet.CreateRow(i + 1);
                row1.HeightInPoints = 21;
                row1.CreateCell(0).SetCellValue(i);
                row1.GetCell(0).CellStyle = setborder;
                row1.CreateCell(1).SetCellValue(data[i].account);
                row1.GetCell(1).CellStyle = setborder;
                row1.CreateCell(2).SetCellValue(Convert.ToString(data[i].name));
                row1.GetCell(2).CellStyle = setborder;
                row1.CreateCell(3).SetCellValue($"{(data[i].sex == 0 ? '男' : '女')}");
                row1.GetCell(3).CellStyle = setborder;
                row1.CreateCell(4).SetCellValue(Convert.ToString(data[i].company));
                row1.GetCell(4).CellStyle = setborder;
                row1.CreateCell(5).SetCellValue(Convert.ToString(data[i].phone));
                row1.GetCell(5).CellStyle = setborder;
                row1.CreateCell(6).SetCellValue(Convert.ToString(data[i].email));
                row1.GetCell(6).CellStyle = setborder;
                row1.CreateCell(7).SetCellValue($"{(data[i].state == 1 ? "正常" : "停用")}");
                row1.GetCell(7).CellStyle = setborder;
                row1.CreateCell(8).SetCellValue(Convert.ToString(data[i].create_op_name));
                row1.GetCell(8).CellStyle = setborder;
                row1.CreateCell(9).SetCellValue(Convert.ToString(data[i].create_op_date.ToString("yyyy-MM-dd")));
                row1.GetCell(9).CellStyle = setborder;
            }
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            book.Write(ms);
            ms.Seek(0, SeekOrigin.Begin);
            DateTime dttime = DateTime.Now;
            string datetime = dttime.ToString("yyyy-MM-dd");
            string filename = "用户列表导出" + datetime + ".xls";
            return File(ms, "application/vns.ms-excel", filename);
        }

        /// <summary>
        ///  停用（修改用户状态）
        /// </summary>
        /// <param state="1"></param>
        /// <returns></returns>
        [HttpPut("{userId}")]
        public async Task<Message> PutUserState(int userId)
        {
            return await _userBusiness.PutUserState(userId);
        }

        /// <summary>
        ///  重置密码（修改用户密码为123456）
        /// </summary>
        /// <param state="1"></param>
        /// <returns></returns>
        [HttpPut("{userId}")]
        public async Task<Message> PutUserPwd(int userId)
        {
            return await _userBusiness.PutUserPwd(userId);
        }

        /// <summary>
        /// 添加用户信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<Message> PostUserInfo([FromBody] DtoUserControl query)
        {
            var account = await _userListrepository.QuerySingleData(m => m.account == query.account);
            if (account == null)
            {
                return await _userBusiness.InsertUserInfo(query);
            }
            return new Message("该用户名已被注册!", false, 202);
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        /// 
        [HttpPost]
        public async Task<Message> PutUserInfo([FromBody] DtoUserControl query)
        {
            return await _userBusiness.PutUserInfo(query);

        }

        /// <summary>
        /// 删除用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        /// 
        [HttpDelete]
        public async Task<Message> DeleteUserInfo(int userId)
        {
            return await _userBusiness.DeleteUserInfo(userId);
        }
    }
}
